package com.ego.item.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ego.common.pojo.PageResult;
import com.ego.exception.enums.ExceptionEnum;
import com.ego.exception.exception.EgoException;
import com.ego.item.bo.SpuBo;
import com.ego.item.mapper.*;
import com.ego.item.pojo.Sku;
import com.ego.item.pojo.Spu;
import com.ego.item.pojo.SpuDetail;
import com.ego.item.pojo.Stock;
import com.ego.item.service.GoodsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class GoodsServiceImpl implements GoodsService {

    @Resource
    private SpuMapper spuMapper;

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private BrandMapper brandMapper;

    @Resource
    private SkuMapper skuMapper;

    @Resource
    private StockMapper stockMapper;

    @Resource
    private SpuDetailMapper spuDetailMapper;

    @Resource
    private AmqpTemplate amqpTemplate;

//    @Override
//    @Transactional(readOnly = true)
//    public PageResult<SpuBo> page(String key, Boolean saleable, Integer page, Integer rows) {
//        PageResult<SpuBo> pageResult = null;
//        try {
//            //查询总记录数
//            QueryWrapper<Spu> wrapper = new QueryWrapper<>();
//            wrapper.like(StringUtils.isNotEmpty(key),"title",key)//过滤条件
//                    .eq(saleable != null,"saleable",saleable);//上架或下架
//            Page<Spu> spuPage = spuMapper.selectPage(new Page<>(page, rows), wrapper);
//
//            List<Spu> spuList = spuPage.getRecords();//获取Spu集合
//            List<SpuBo> spuBoList = new ArrayList<>(spuList.size());//新建SpuBo
//            spuList.forEach(spu -> {
//                //封装商品分类
//                SpuBo spuBo = new SpuBo();
//                spuBo.setId(spu.getId());
//                spuBo.setTitle(spu.getTitle());
//                spuBo.setBrandId(spu.getBrandId());
//                spuBo.setCid1(spu.getCid1());
//                spuBo.setCid2(spu.getCid2());
//                spuBo.setCid3(spu.getCid3());
//                List<Long> cidList = Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3());
//                String categoryName = "";
//                List<Category> categoryList = categoryMapper.selectBatchIds(cidList);
//                for (int i = 0; i < categoryList.size(); i++) {//拼接
//                    categoryName += categoryList.get(i).getName();
//                    if (i < categoryList.size()-1) {
//                        categoryName += "/";
//                    }
//                }
//                spuBo.setCategoryNames(categoryName);
//                //封装品牌
//                Brand brand = brandMapper.selectById(spu.getBrandId());
//                spuBo.setBrandName(brand.getName());
//
//                spuBoList.add(spuBo);
//            });
//            pageResult = new PageResult<>(spuPage.getTotal(),spuBoList);
//        }catch (Exception e){
//            EgoException.error(log, ExceptionEnum.GOODS_PAGE_ERROR,e);
//        }
//        return pageResult;
//    }

    @Override
    @Transactional(readOnly = true)
    public PageResult<SpuBo> page(String key, Boolean saleable, Integer page, Integer rows) {
        PageResult<SpuBo> pageResult = null;
        try {
            //查询总记录数
            QueryWrapper<Spu> wrapper = new QueryWrapper<>();
            wrapper.like(StringUtils.isNotEmpty(key),"title",key)//过滤条件
                    .eq(saleable != null,"saleable",saleable);//上架或下架

            Integer total = spuMapper.selectCount(wrapper);
            //自定义分页查询
            Integer startRows = (page-1)*rows;
            List<SpuBo> spuBoList = spuMapper.selectPageByXml(key,saleable,startRows,rows);
            pageResult = new PageResult<>(total.longValue(),spuBoList);
        }catch (Exception e){
            EgoException.error(log, ExceptionEnum.GOODS_PAGE_ERROR,e);
        }
        return pageResult;
    }

    @Override
    @Transactional
    public void save(SpuBo spuBo) {
        try {
            Date now = new Date();
            //保存spu
            spuBo.setValid(true);
            spuBo.setCreateTime(now);
            spuBo.setLastUpdateTime(spuBo.getCreateTime());
            spuBo.setSaleable(true);
            spuMapper.insert(spuBo);

            Long spuId = spuBo.getId();

            //保存sku
            List<Sku> skuList = spuBo.getSkus();
            skuList.forEach(sku -> {
                sku.setSpuId(spuId);
                sku.setCreateTime(now);
                sku.setLastUpdateTime(now);
                skuMapper.insert(sku);
                //保存stock
                Stock stock = sku.getStock();
                stock.setSkuId(sku.getId());
                stockMapper.insert(stock);
            });

            //保存spu_detail
            SpuDetail spuDetail = spuBo.getSpuDetail();
            spuDetail.setSpuId(spuId);
            spuDetailMapper.insert(spuDetail);

            //异步发送消息
            amqpTemplate.convertAndSend("item.insert",spuId);

        }catch (Exception e){
            EgoException.error(log,ExceptionEnum.GOODS_SAVE_ERROR,e);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public SpuDetail querySpuDetailById(Integer id) {
        SpuDetail spuDetail = null;
        try {
            spuDetail = spuDetailMapper.selectById(id);
        } catch (Exception e) {
            EgoException.error(log,ExceptionEnum.SPU_DETAIL_NOT_FOUND,e);
        }
        return spuDetail;
    }

    @Override
    @Transactional(readOnly = true)
    public List<Sku> querySkuBySpuId(Long spuId) {
        List<Sku> skus = null;
        try {
            // 查询sku
            Map<String, Object> map = new HashMap<>(1);
            map.put("spu_id", spuId);
            skus = skuMapper.selectByMap(map);
            for (Sku sku : skus) {
                // 同时查询出库存
                sku.setStock(stockMapper.selectById(sku.getId()));
            }
        } catch (Exception e) {
            EgoException.error(log,ExceptionEnum.SKU_NOT_FOUND,e);
        }
        return skus;
    }

    @Override
    @Transactional
    public void update(SpuBo spuBo) {
        try {
            HashMap<String, Object> map = new HashMap<>(1);
            Long spuId = spuBo.getId();
            map.put("spu_id",spuId);
            List<Sku> skus = skuMapper.selectByMap(map);
            if (!CollectionUtils.isEmpty(skus)) {
                skus.forEach(sku -> {
                    stockMapper.deleteById(sku.getId());//先删库存
                    skuMapper.deleteById(sku.getId());//再删sku
                });
            }
            //新增sku和库存
            List<Sku> skuList = spuBo.getSkus();
            skuList.forEach(sku -> {
                sku.setSpuId(spuId);
                sku.setCreateTime(new Date());
                sku.setLastUpdateTime(sku.getCreateTime());
                skuMapper.insert(sku);

                Stock stock = sku.getStock();
                stock.setSkuId(sku.getId());
                stockMapper.insert(stock);
            });
            //更新detail
            spuDetailMapper.updateById(spuBo.getSpuDetail());
            //更新spu
            Spu spu = new Spu();
            spu.setId(spuId);
            spu.setBrandId(spuBo.getBrandId());
            spu.setCid1(spuBo.getCid1());
            spu.setCid2(spuBo.getCid2());
            spu.setCid3(spuBo.getCid3());
            spu.setTitle(spuBo.getTitle());
            spu.setSubTitle(spuBo.getSubTitle());
            spu.setSaleable(spuBo.getSaleable());
            spu.setValid(spuBo.getValid());
            spu.setLastUpdateTime(new Date());
            spuMapper.updateById(spu);

            //异步发送消息
            amqpTemplate.convertAndSend("item.update",spuId);
        }catch (Exception e){
            EgoException.error(log,ExceptionEnum.GOODS_UPDATE_ERROR,e);
        }
    }

    @Override
    @Transactional
    public void delete(Integer id) {
        try {
            Spu spu = new Spu();
            spu.setId(id.longValue());
            spu.setValid(false);//设置状态为已删除
            spu.setSaleable(false);
            spu.setLastUpdateTime(new Date());
            spuMapper.updateById(spu);

            //异步发送消息
            amqpTemplate.convertAndSend("item.delete",id);
        }catch (Exception e){
            EgoException.error(log,ExceptionEnum.DELETE_GOODS_ERROR,e);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public PageResult<SpuBo> pageForES(Integer pageNo, Integer size) {
        PageResult<SpuBo> pageResult = null;
        try {
            //查询总记录数
            QueryWrapper<Spu> wrapper = new QueryWrapper<>();
            wrapper.eq("saleable",true)
                    .eq("valid",true);
            Integer total = spuMapper.selectCount(wrapper);
            //自定义分页查询
            Integer startRows = (pageNo-1)*size;
            List<SpuBo> spuBoList = spuMapper.selectPageForESByXml(startRows,size);
            pageResult = new PageResult<>(total.longValue(),spuBoList);
        }catch (Exception e){
            EgoException.error(log, ExceptionEnum.GOODS_PAGE_ERROR,e);
        }
        return pageResult;
    }

    @Override
    public SpuBo queryGoodsById(Long id) {
        /**
         * 第一页所需信息如下：
         * 1.商品的分类信息、所属品牌、商品标题、商品卖点（子标题）
         * 2.商品的包装清单、售后服务
         */
        Spu spu=this.spuMapper.selectById(id);
        SpuDetail spuDetail = this.spuDetailMapper.selectById(spu.getId());


        QueryWrapper<Sku> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("spu_id", spu.getId());
        List<Sku> skuList = this.skuMapper.selectList(queryWrapper);

        List<Long> skuIdList = new ArrayList<>();
        for (Sku sku : skuList){
            skuIdList.add(sku.getId());
        }

        List<Stock> stocks = this.stockMapper.selectBatchIds(skuIdList);

        for (Sku sku:skuList){
            for (Stock stock : stocks){
                if (sku.getId().equals(stock.getSkuId())){
                    sku.setStock(stock);
                }
            }
        }

        return SpuBo.builder()
                .id(spu.getId())
                .brandId(spu.getBrandId())
                .cid1(spu.getCid1())
                .cid2(spu.getCid2())
                .cid3(spu.getCid3())
                .brandId(spu.getBrandId())
                .title(spu.getTitle())
                .subTitle(spu.getSubTitle())
                .saleable(spu.getSaleable())
                .valid(spu.getValid())
                .createTime(spu.getCreateTime())
                .lastUpdateTime(spu.getLastUpdateTime())
                .skus(skuList)
                .spuDetail(spuDetail).build();
    }

    @Override
    @Transactional(readOnly = true)
    public Sku findSkuBySkuId(Long skuId) {
        return skuMapper.selectById(skuId);
    }

    @Override
    @Transactional(readOnly = true)
    public List<Sku> findSkuListBySkuIdList(List<Long> skuIdList) {
        return skuMapper.selectBatchIds(skuIdList);
    }

    @Override
    @Transactional
    public Boolean reduceStock(List<Map<Object, Object>> list) {
        Boolean result = true;
        for (int i = 0; i < list.size(); i++) {
            Map<Object, Object> map = list.get(i);
            Long skuId = Long.valueOf(String.valueOf(map.get("skuId")));
            Integer num = (Integer) map.get("num");
            //先加锁
            stockMapper.lockStock(skuId);
            //再减库存
            int count = stockMapper.reduceStock(skuId,num);
            if (count == 0) {
                result = false;
                break;
            }
        }
        int a = 1/0;
        return result;
    }
}
